"""
    Socket 对象的常用方法

        方法名称                  功能描述
        bind((ip, port))        绑定 ip地址和端口。
        listen(N)               开始TCP监听，N表示操作系统挂起的最大连接数量，取值范围 1-5之间，一般设置 5。
        accept()                被动接收TCP客户端连接，阻塞式。
        connect((ip, port))     主动初始化TCP服务器连接。
        recv(size)              接受TCP数据，返回值为字符串类型，size表示要接收的最大数据量。

        send(str)               发送TCP数据，返回值是要发送的字节数量。
        sendall(str)            完整发送TCP数据，将 str 中的数据发送到连接的套接字，返回之前尝试发送所有数据，如果成功为 None，失败抛出异常。
        recvfrom()              接收UDP数据，返回值为一个元组(data,address)，data表示接收的数据，address表示发送数据的套接字地址。
        sendto(data, (ip, port))  发送UDP数据，返回值是发送的字节数。
        close()                 关闭套接字
"""
from socket import socket, AF_INET, SOCK_STREAM

# AF_INET 用于 Internet 之间的进程通信
# SOCK_STREAM 表示的是用 TCP 协议编程

"""
    TCP服务端流程如下：
        1、使用socket类创建一个套接字对象
        2、使用bind((ip, port))方法绑定ip地址和端口号
        3、使用listen()方法开始TCP监听
        4、使用accept()方法等待客户端的连接
        5、使用recv() /send()方法接收/发送数据
        6、使用close()关闭套接字
"""

# 1、创建 socket 对象
server_socket = socket(AF_INET, SOCK_STREAM)
# 2、绑定ip地址和端口
ip = '127.0.0.1'
port = 8888
server_socket.bind((ip, port))
# 3、使用listen()方法开始TCP监听
server_socket.listen(5)
print('服务器已启动')
# 4、等待客户端连接
client_socket, client_addr = server_socket.accept()     # 系列解包赋值
# 5、接收来自客户端的数据
data = client_socket.recv(1024)
print('客户端发过来的数据为：', data.decode('utf-8'))
# 6、关闭socket
server_socket.close()
